package cn.lanqiao.springboot.interceptor;

import cn.lanqiao.springboot.entity.Menu;
import cn.lanqiao.springboot.service.MenuService;
import cn.lanqiao.springboot.util.CurrentUserUtil;
import cn.lanqiao.springboot.util.Result;
import cn.lanqiao.springboot.vo.UserVO;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;


@Component
public class LoginInterceptorRedis implements HandlerInterceptor {
    @Autowired
    MenuService menuService;

    @Autowired
    RedisTemplate<String, Object> redisTemplate;

    /**
     * 使用拦截器实现JWT登录验证
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        try {
            //获得token操作
            String token = request.getHeader("Authorization");
            if (token == null) {
                return failResult(611, "请先登录！！", response);
            }
            token = token.substring(7); // 去除bearer头
            //从Redis中获得user, 完成认证操作！
            Object userVO = redisTemplate.opsForValue().get(token);
            if (userVO == null) {
                return failResult(612, "登录失效，请重新登录！！", response);
            }
            //刷新token
            redisTemplate.expire(token, 3, TimeUnit.MINUTES);
            //将用户信息存入threadlocal。
            CurrentUserUtil.set((UserVO) userVO);
            //鉴权操作
            //1、获得浏览器请求地址 /user/list
            String url = request.getRequestURI();
            if (url.equals("/menu/list")) {
                return true;
            }
            //2、roleId获得权限集合 roleId - List<Url>
            List<Menu> menuList = menuService.getList(((UserVO) userVO).getRoleId());
            //3、请求地址是否在权限集合里
            for (Menu menu : menuList) {
                if (menu.getAuthorize() != null) {
                    if (url.matches(menu.getAuthorize())) {
                        return true;
                    }
                }
            }
            return failResult(600, "权限不足！", response);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 验证失败统一向前端返回错误结果
     *
     * @param code     错误码
     * @param message  错误信息
     * @param response 响应对象
     */
    public boolean failResult(int code, String message, HttpServletResponse response) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();//使用jackson，也可以使用fastjson
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().print(objectMapper.writeValueAsString(Result.error(code, message)));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }
}
